﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;

namespace Shp.Web.UI.WebControls.Iconized
{
   internal class IconizedSharedBase
   {
      #region Fields
      private IIconizedButton _button;
      private WebControl _baseControl;

      /// <summary>
      /// List of CSS resources for Release builds.
      /// </summary>
      private List<string> _releaseCssResources = new List<string>()
      {
         "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.core.min.css"
      };

      /// <summary>
      /// List of CSS resources for Debug builds.
      /// </summary>
      private List<string> _debugCssResources = new List<string>()
      {
         "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.core.debug.css",
         "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.bg.debug.css"
      };
      #endregion Fields

      #region Properties
      /// <summary>
      /// Gets or sets the button skin.
      /// </summary>
      /// <value>The button skin.</value>
      internal ButtonSkinType ButtonSkin
      {
         get
         {
            object o = this._button.ControlViewState["_buttonSkin"];
            return (o != null) ? (ButtonSkinType)o : ButtonSkinType.Gray;
         }

         set { this._button.ControlViewState["_buttonSkin"] = value; }
      }

      /// <summary>
      /// Gets or sets the custom CSS class.
      /// </summary>
      /// <value>The custom CSS class.</value>
      internal string CustomCssClass
      {
         get
         {
            object o = this._button.ControlViewState["_customCssClass"];
            return (o != null) ? o.ToString() : string.Empty;
         }

         set { this._button.ControlViewState["_customCssClass"] = value; }
      }

      /// <summary>
      /// Gets or sets the type of the icon.
      /// </summary>
      /// <value>The type of the icon.</value>
      internal IconType IconType
      {
         get
         {
            object o = this._button.ControlViewState["_iconType"];
            return (o != null) ? (IconType)o : IconType.None;
         }

         set { this._button.ControlViewState["_iconType"] = value; }
      }

      /// <summary>
      /// Gets or sets the type of the custom icon.
      /// </summary>
      /// <value>The type of the custom icon.</value>
      internal string CustomIconType
      {
         get
         {
            object o = this._button.ControlViewState["_customIconType"];
            return (o != null) ? o.ToString() : string.Empty;
         }

         set { this._button.ControlViewState["_customIconType"] = value; }
      }

      /// <summary>
      /// Gets or sets the icon position.
      /// </summary>
      /// <value>The icon position.</value>
      internal IconPositionType IconPosition
      {
         get
         {
            object o = this._button.ControlViewState["_iconPosition"];
            return (o != null) ? (IconPositionType)o : IconPositionType.None;
         }

         set { this._button.ControlViewState["_iconPosition"] = value; }
      }

      /// <summary>
      /// Gets or sets a value indicating whether [display mouse out style].
      /// </summary>
      /// <value>
      /// 	<c>true</c> if [display mouse out style]; otherwise, <c>false</c>.
      /// </value>
      internal bool DisplayMouseOutStyle
      {
         get
         {
            object o = this._button.ControlViewState["_displayMouseOutStyle"];
            return (o != null) ? Convert.ToBoolean(o) : true;
         }

         set { this._button.ControlViewState["_displayMouseOutStyle"] = value; }
      }

      /// <summary>
      /// Gets or sets a value indicating whether [round corners].
      /// </summary>
      /// <value><c>true</c> if [round corners]; otherwise, <c>false</c>.</value>
      internal bool RoundCorners
      {
         get
         {
            object o = this._button.ControlViewState["_roundCorners"];
            return (o != null) ? Convert.ToBoolean(o) : false;
         }

         set { this._button.ControlViewState["_roundCorners"] = value; }
      }

      /// <summary>
      /// Gets the button as it's base WebControl.
      /// </summary>
      /// <value>The base control.</value>
      internal WebControl BaseControl
      {
         get
         {
            if (this._baseControl == null)
               this._baseControl = (this._button as WebControl);
            return this._baseControl;
         }
      }
      #endregion Properties

      #region Methods
      /// <summary>
      /// Builds the CSS class.
      /// </summary>
      internal void BuildCssClass()
      {
         string cssClass = "shp-btn ";

         if (!this._button.DisplayMouseOutStyle)
         {
            cssClass += "ni ";
         }

         if (this._button.RoundCorners)
         {
            cssClass += "round ";
         }

         if (this._button.IconType != IconType.None)
         {
            switch (this._button.IconPosition)
            {
               case IconPositionType.None:
                  cssClass += (this._button.Text.Trim() != string.Empty) ? "shp-btn-ico-lt " : "shp-btn-ico-s ";
                  break;
               case IconPositionType.Left:
                  cssClass += "shp-btn-ico-lt ";
                  break;
               case IconPositionType.Right:
                  cssClass += "shp-btn-ico-rt ";
                  break;
               case IconPositionType.Solo:
                  cssClass += "shp-btn-ico-s ";
                  // solo icon does not allow text, so remove the text.
                  this._button.Text = string.Empty;
                  break;
               case IconPositionType.SmallSolo:
                  cssClass += "shp-btn-ico-ss ";
                  // solo icon does not allow text, so remove the text.
                  this._button.Text = string.Empty;
                  break;
            }
         }

         if (this._button.ButtonSkin == ButtonSkinType.Custom)
         {
            if (!string.IsNullOrEmpty(this._button.CustomCssClass))
            {
               cssClass += this._button.CustomCssClass;
            }
         }
         else
         {
            cssClass += this._button.ButtonSkin.ToString("G").ToLower();
         }

         if (!this._button.Enabled)
         {
            cssClass += " disabled";
         }

         this._button.CssClass = cssClass;
      }

      /// <summary>
      /// Registers the style web references.
      /// </summary>
      internal void RegisterStyles()
      {
         // add the supporting resources and make sure that the resource is not already added.
         //string contextKey = this.GetType().ToString();
         string contextKey = this._button.GetType().Assembly.GetName().FullName;
         List<string> resources = null;

         if (this._button.CurrentContext.Items[contextKey] == null)
         {
            resources = new List<string>();

            // add the core css resources
#if(DEBUG)
            resources.AddRange(this._debugCssResources);
            this.RegisterResourceWithPage(this._debugCssResources);
#else
            resources.AddRange(this._releaseCssResources);
            this.RegisterResourceWithPage(this._releaseCssResources);
#endif
         }
         else
         {
            resources = (List<string>)this._button.CurrentContext.Items[contextKey];
         }

         string iconCssResource = this.GetIconCssWebResource(this._button.IconType);
         if (!string.IsNullOrEmpty(iconCssResource))
         {
            if (string.IsNullOrEmpty(resources.Where(i => i == iconCssResource).SingleOrDefault()))
            {
               // add the icon-specific css resource
               resources.Add(iconCssResource);
               this.RegisterResourceWithPage(iconCssResource);
            }
         }
         this._button.CurrentContext.Items[contextKey] = resources;
      }

      /// <summary>
      /// Gets the icon CSS web resource.
      /// </summary>
      /// <param name="iconType">Type of the icon.</param>
      /// <returns></returns>
      internal string GetIconCssWebResource(IconType iconType)
      {
         if ((iconType == IconType.None) && (iconType == IconType.Custom))
            return string.Empty;

         string startsWith = iconType.ToString("G")[0].ToString().ToLower();

         if ((new List<string>() { "a" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.a.css";
         if ((new List<string>() { "b" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.b.css";
         if ((new List<string>() { "c" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.c.css";
         if ((new List<string>() { "d" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.d.css";
         if ((new List<string>() { "e" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.e.css";
         if ((new List<string>() { "f" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.f.css";
         if ((new List<string>() { "g", "h", "i", "j", "k", "l" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.g-h-i-j-k-l.css";
         if ((new List<string>() { "m", "n", "o" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.m-n-o.css";
         if ((new List<string>() { "p" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.p.css";
         if ((new List<string>() { "r", "s" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.r-s.css";
         if ((new List<string>() { "t" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.t.css";
         if ((new List<string>() { "u", "v", "w", "x", "z" }).Contains(startsWith)) return "Shp.Web.UI.WebControls.Iconized.assets.css.shp.btn.ico.u-v-w-x-z.css";
         else return string.Empty;
      }

      /// <summary>
      /// Registers the resource with the page.
      /// </summary>
      /// <param name="resource">The resource.</param>
      internal void RegisterResourceWithPage(string resource)
      {         
         string href = this._button.Page.ClientScript.GetWebResourceUrl(this.GetType(), resource);
         this._button.Page.Header.Controls.Add(new CssLink() { Href = href });
      }

      /// <summary>
      /// Registers the resources with the page.
      /// </summary>
      /// <param name="resource">The resource.</param>
      internal void RegisterResourceWithPage(IEnumerable<string> resources)
      {
         foreach (string resx in resources)
            this.RegisterResourceWithPage(resx);
      }
      #endregion Methods

      #region Ctors
      internal IconizedSharedBase(IIconizedButton button)
      {         
         this._button = button;
      }
      #endregion Ctors
   }
}